#pragma once
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#define DEFAULT_CAPACITY 4
// 报错宏
#define ERR_EXIT(name)      \
    do                      \
    {                       \
        perror(name);       \
        exit(EXIT_FAILURE); \
    } while (0)

template <class T>
class Stack
{
public:
    // 构造函数，初始开辟4个容量
    Stack(int n = DEFAULT_CAPACITY) : _arr(new T[n]), _size(0), _capacity(n)
    {
        if (_arr == nullptr)
            ERR_EXIT("malloc");
    }

    void PushBack(const T &val);
    ~Stack()
    {
        delete[] _arr;
        _arr = nullptr;
        _size = _capacity = 0;
        std::cout << "delete success!" << std::endl;
    }

    void Debug() const;

private:
    T *_arr;
    int _size;
    int _capacity;
};

template <class T>
void Stack<T>::PushBack(const T &val)
{
    // 插入空间要判断是否需要扩容
    if (_size == _capacity)//_capacity默认为4
    {
        // 开辟空间
        T *tmp = new T[2 * _capacity];
        // 拷贝内容
        memcpy(tmp, _arr, sizeof(T) * _size);
        // 删除原有空间
        delete[] _arr;
        // 赋值回去
        _arr = tmp;
        std::cout << "扩容成功！" << std::endl;
        _capacity = 2 * _capacity;
    }

    _arr[_size++] = val;
}

template <class T>
void Stack<T>::Debug() const
{
    for (int i = 0; i < _size; i++)
    {
        std::cout << _arr[i] << " ";
    }
    std::cout << std::endl;
}
